﻿#include "ProcessCore.h"

#define FLUSH_INTERVAL_TIME 200

ProcessCore::ProcessCore(QObject *parent)
	: QObject(parent)
{
	initialize();
	initSignalAndSlot();
	qDebug() << "ProcessCore Init Finished...";
	qDebug() << "ProcessCore Thread:" << this->thread();
}

ProcessCore::~ProcessCore()
{
	As::uninitGlobalDataPool();
	delete  m_pPCIctrl;
	delete m_pCommunicator;
	delete m_pDataProcessThread;
	delete m_pExcleExportor;

	m_pPCIThread1->deleteLater();
	m_pPCIThread2->deleteLater();
	m_pPCIThread3->deleteLater();
	m_pPCIThread4->deleteLater();
	m_pPCIThread5->deleteLater();
}

void ProcessCore::initCommunicatorFields(HSS::PortInformation portinfo)
{
	m_pCommunicator->setPortInformation(portinfo);
	qDebug() << "SerialPort Information Init Finished...";
}

bool ProcessCore::loadProfile(QString xmlFilePath)
{
	m_pPCIctrl->loadProfile(xmlFilePath);
	return m_pPCIctrl->prepare();
}

bool ProcessCore::startWork()
{
	if (!hasLoadedProfile)
	{
		m_pPCIctrl->loadProfile(PtrConfig->xmlPath);
		m_pPCIctrl->prepare();
		hasLoadedProfile = true;
	}
	bool flag = m_pPCIctrl->start();
	if (!flag)
	{
		return false;
	}
	return true;
}

void ProcessCore::pauseWork()
{
	m_timer.stop();
}

void ProcessCore::continueWork()
{
	m_timer.start(FLUSH_INTERVAL_TIME);
}

bool ProcessCore::stopWork()
{
	m_timer.stop();
	return m_pPCIctrl->stop();
}

void ProcessCore::averageProcessDataMatAndExtrastGirdle()
{
	//子线程做平均值处理
	m_pDataProcessThread->invokeFn(this, "computeAverageMat");
}

void ProcessCore::prepareProcess3DDatas()
{
	m_pDataProcessThread->invokeFn([this]() {
		computeAverageMat();
		transformToQVector3D();
		extrastGirdleLevel();
		sortHeightList();
		emit extrastGirdleOver();
		emit update3DWidgetSlider();
		});
}

void ProcessCore::computeAverageMat()
{
	QMap<int, QVector<cv::Mat>> dataMap = PtrCoreData->getMatDatasMap();
	if (dataMap.isEmpty())
	{
		qDebug() << "没有可用数据，请采集成功后再进行导出......";
		return;
	}
	QMap<int, QVector<cv::Mat>>::const_iterator it = dataMap.constBegin();
	while (it != dataMap.constEnd()) {
		int height = it.key();
		QVector<cv::Mat> matVec = it.value();
		for (int i = 0; i < matVec.size(); i++) {
			if (matVec[i].size() != matVec[0].size()) {
				// 大小不一致，返回
				qDebug() << "矩阵大小不一致";
				return ;
			}
		}
		cv::Mat sumMat = matVec[0].clone(); // 创建一个用于存储矩阵和的变量

	// 逐个矩阵相加
		for (int j = 0; j < matVec.size(); ++j) {
			cv::add(sumMat, matVec[j], sumMat);
		}
		cv::divide(sumMat, matVec.size(), sumMat);
		PtrCoreData->insertAverageMatMap(height, sumMat);
		it++;
	}
}

void ProcessCore::transformToQVector3D()
{
	QMap<int, cv::Mat> matMap = PtrCoreData->getAverageMatMap();
	QList<int> keys = matMap.keys();
	for (int i = 0; i < keys.size(); ++i)
	{
		int height = keys.at(i);
		cv::Mat mat = matMap.value(height);
		QVector<QVector3D> vec3DVec;
		for (int i = 0;i<mat.rows;i++)
		{
			float *ptr = mat.ptr<float>(i);
			for (int j = 0;j < mat.cols;j++)
			{
				if (height == 1)
				{
					ptr[j] = 0.1;
				}
				vec3DVec << QVector3D(j, i, ptr[j]);
			}
		}
		PtrCoreData->insertVec3DMap(height, vec3DVec);
	}
	qDebug() << "点云数据处理完毕......";
}

void ProcessCore::sortHeightList()
{
	PtrCoreData->sortHeightList();
}

void ProcessCore::extrastGirdleLevel()
{
	PtrCoreData->extrastGirdleMat();
}

void ProcessCore::exportToExcel()
{
	m_pDataProcessThread->invokeFn(m_pExcleExportor, "exportDataToMicrosoftExcel");
	//m_pExcleExportor->exportDataToMicrosoftExcel();
}

//void ProcessCore::timerStart()
//{
//	m_timer.start(FLUSH_INTERVAL_TIME);
//}

void ProcessCore::dataReadyToUi()
{
	emit sendLatestPCIDatas(m_pPCIctrl->getIndex());
}

void ProcessCore::onceDataMatsCollectOver(int height)
{
	m_pPCIctrl->stop();
	PtrCoreData->updateOnceCollectDatasWithHeight();
}

void ProcessCore::updatePortInformation(HSS::PortInformation portinfo)
{
	m_pCommunicator->setPortInformation(portinfo);
	qDebug() << "SerialPort Information Update Finished...";
}

void ProcessCore::processOnceDataFromPCI(int index)
{
	PtrCoreData->handleDatas(index);
	if (!m_flag)
	{
		m_timer.start(FLUSH_INTERVAL_TIME);
		qDebug() << "timer Start!";
		m_flag = true;
	}
	
}

void ProcessCore::distributeThreadToPCIData(int index)
{
	m_pPCIProcessThread->invokeFn(this, "processOnceDataFromPCI");

	switch (index)
	{
	case 0:
	case 5:
		m_pPCIThread1->invokeFn(this, "processOnceDataFromPCI");
		break;
	case 1:
	case 6:
		m_pPCIThread2->invokeFn(this, "processOnceDataFromPCI");
		break;
	case 2:
	case 7:
		m_pPCIThread3->invokeFn(this, "processOnceDataFromPCI");
		break;
	case 3:
	case 8:
		m_pPCIThread4->invokeFn(this, "processOnceDataFromPCI");
		break;
	case 4:
	case 9:
		m_pPCIThread5->invokeFn(this, "processOnceDataFromPCI");
		break;
	default:
		break;
	}
}

void ProcessCore::initialize()
{
	As::registerConfigMetaType<ConfigData>();
	As::registerGlobalMetaType<CoreData>(AsDefine::AsProcessCoreRole);
	As::initGlobalDataPool();

	m_pPCIctrl = new PCIControl();
	m_pCommunicator = new Communicator();
	m_pDataProcessThread = new AsThread(this);
	m_pPCIProcessThread = new AsThread(this);
	m_pPCIThread1 = new AsThread(this);
	m_pPCIThread2 = new AsThread(this);
	m_pPCIThread3 = new AsThread(this);
	m_pPCIThread4 = new AsThread(this);
	m_pPCIThread5 = new AsThread(this);
	//m_asThreadVec << m_pPCIThread1 << m_pPCIThread2 << m_pPCIThread3 << m_pPCIThread4 << m_pPCIThread5;
	m_pExcleExportor = new DataExportor();

}

void ProcessCore::initSignalAndSlot()
{
	connect(&m_timer, &QTimer::timeout, this, &ProcessCore::dataReadyToUi);
	//connect(PtrCoreData, &CoreData::allowTimerStart, this, &ProcessCore::timerStart);
	connect(PtrCoreData, &CoreData::getDatasOfThisHeightOver, [this]() {
		//收到场信号或者超出设定的
		this->stopWork();
		m_flag = false;
		qDebug() << "ProcessCore StopWork...";
		//收集数据并清空容器
		PtrCoreData->updateOnceCollectDatasWithHeight();
		emit shouleReleaseButtons();

		});
	connect(m_pPCIctrl, &PCIControl::getDataOnceOver, this, &ProcessCore::processOnceDataFromPCI);

	//connect(m_pCommunicator, &Communicator::oneHeightDataEnd,this,&ProcessCore:: )
}

void ProcessCore::initPCI()
{
	//PCIControl构造函数已经实现下列方法
	//m_pPCIctrl->loadProfile(PtrConfig->xmlPath);
	//m_pPCIctrl->prepare();
}
